use ndarray::array;
use rstest::rstest;

use crate::tests::fixtures::{
    random_missing_tile_policy,
    random_tile_selection_policy,
    random_tile_type,
    random_vacancy_policy,
    RANDOM_TILES,
    RANDOM_USIZE,
};
use crate::tiling::slot_grid::tests::create_grid_slot_with_predecessor;
use crate::tiling::tiles::tile_list::TileList;
use crate::tiling::tiles::{ArrayInitializable, TileConnectionArray};
use crate::tiling::SlotGrid;

#[rstest]
#[case::no_successors_0_1(0, 1, false)]
#[case::no_successors_1_0(1, 0, false)]
#[case::no_successors_2_5(2, 5, false)]
#[case::no_successors_5_3(5, 3, false)]
#[case::no_successors_1_1(1, 1, false)]
#[case::no_successors_2_2(2, 2, false)]
#[case::no_successors_1_4(1, 4, false)]
#[case::no_successors_4_3(4, 3, false)]
#[case::no_successors_4_4(4, 4, false)]
#[case::one_successor_1_3(1, 3, true)]
#[case::one_successor_2_3(2, 3, true)]
#[case::one_successor_3_1(3, 1, true)]
#[case::one_successor_3_2(3, 2, true)]
#[case::one_successor_3_4(3, 4, true)]
#[case::one_successor_4_1(4, 1, true)]
#[case::two_successors_1_2(1, 2, true)]
#[case::four_successors_3_3(3, 3, true)]
fn test_current_slot_has_successors(
    #[case] row: usize,
    #[case] col: usize,
    #[case] expected_result: bool,
) {
    let tile_list = TileList {
        tiles: RANDOM_TILES.iter().cloned().collect(),
        horizontal_connector_names: vec![],
        vertical_connector_names: vec![],
        tile_type: random_tile_type(),
    };
    let slot_grid = SlotGrid {
        grid: array![
            [None, None, None, None, None],
            [
                None,
                create_grid_slot_with_predecessor(Some((1, 2))),
                create_grid_slot_with_predecessor(Some((1, 3))),
                create_grid_slot_with_predecessor(Some((2, 3))),
                None,
            ],
            [
                None,
                create_grid_slot_with_predecessor(Some((3, 1))),
                create_grid_slot_with_predecessor(Some((1, 2))),
                create_grid_slot_with_predecessor(Some((3, 3))),
                None,
            ],
            [
                None,
                create_grid_slot_with_predecessor(Some((3, 2))),
                create_grid_slot_with_predecessor(Some((3, 3))),
                create_grid_slot_with_predecessor(None),
                create_grid_slot_with_predecessor(Some((3, 3))),
            ],
            [
                None,
                create_grid_slot_with_predecessor(None),
                create_grid_slot_with_predecessor(Some((4, 1))),
                create_grid_slot_with_predecessor(Some((3, 3))),
                create_grid_slot_with_predecessor(Some((3, 4))),
            ],
        ],
        num_rows: 4,
        num_cols: 4,
        border_tile_id: Some(*RANDOM_USIZE * 17),
        tile_connections: TileConnectionArray::new(&tile_list.tiles),
        tile_list,
        missing_tile_policy: random_missing_tile_policy(),
        tile_selection_policy: random_tile_selection_policy(),
        vacancy_policy: random_vacancy_policy(),
        current_slot: (row, col),
        current_predecessor: None,
        last_leaves: vec![],
        exposed_edge_count: 0,
    };

    let result: bool = slot_grid.current_slot_has_successors();

    assert_eq!(result, expected_result);
}
